home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_12_04 / welstead / uidialgs.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-13  |  10.1 KB  |  334 lines

  1. Welstead: Listing 4
  2.  
  3. // File UIDIALGS.CPP  General dialog boxes
  4.  
  5. #ifndef UIDIALGS_CPP
  6. #define UIDIALGS_CPP
  7.  
  8. #define Uses_TDeskTop
  9. #define Uses_TApplication
  10. #define Uses_TView
  11. #define Uses_TDialog
  12. #define Uses_TLabel
  13. #define Uses_TFileDialog
  14. #define Uses_TSItem
  15. #define Uses_TRadioButtons
  16. #define Uses_TCheckBoxes
  17. #define Uses_TButton
  18. #define Uses_TRect
  19. #define Uses_TInputLine
  20. #define Uses_TEvent
  21. #define Uses_TKeys
  22. #define Uses_MsgBox
  23. #define Uses_TStaticText
  24. #include "uisetvar.cpp"  //includes <tv.h>
  25.  
  26. //For radio buttons and check boxes: 
  27. const MAX_NO_OF_ITEMS = 16;  
  28. //Center hor position on 80 col text screen:
  29. const SCREEN_H_CENTER = 40;  
  30. //Center vert position on 25 row text screen:
  31. const SCREEN_V_CENTER = 12;  
  32. // Min width to accommodate command buttons:
  33. const MIN_BOX_WIDTH = 40;  
  34. typedef char* tpstring;
  35. typedef tpstring tpstring_array[MAX_NO_OF_ITEMS];
  36.  
  37. void radio_dialog (const char *p_title,
  38.    const char *p_descr,void *names, int no_of_items, 
  39.    int item_length, ushort *return_val);
  40. void boolean_dialog (const char *p_title, 
  41.    boolean &answer);
  42. void check_box_dialog (const char *p_title,
  43.    const char *p_descr,void *names, int no_of_items, 
  44.    int item_length, ushort *return_val);
  45. void numeric_dialog (const char* p_title,
  46.    int maxlen, int dec_places, boolean check_max_min,
  47.    float min, float max, tdata_type type_of_data,
  48.    void * p_value);
  49. void get_file_name_dlg (const char *pwild_str,
  50.    const char *ptitle_str,char *file_name);
  51.  
  52. // Implementation
  53.  
  54. void get_tpstring_array (void *names_addr, 
  55.    int no_of_items,int item_length, 
  56.    tpstring_array &the_array) {
  57.    char *p_chr_array;
  58.    p_chr_array = (char *)names_addr;
  59.    int offs = 0;
  60.    for (int i = 0; i < no_of_items; i++)
  61.       {the_array[i] = &p_chr_array[i + offs];
  62.        offs += item_length - 1;}
  63.    return;
  64.    }
  65.  
  66. TRect the_rect (int no_of_items,int item_length,
  67.    int title_len,int descr_len)
  68.    {
  69.    int box_width,box_start,box_line_start,box_length,
  70.        tlen,dlen;
  71.    const int MAX_BOX_LENGTH = 21;
  72.    box_width = item_length + 8;
  73.    tlen = title_len + 4;
  74.    dlen = descr_len + 12;
  75.    if (box_width < tlen) box_width = tlen;
  76.    if (box_width < dlen) box_width = dlen;
  77.    if (box_width < MIN_BOX_WIDTH) 
  78.     box_width = MIN_BOX_WIDTH;
  79.    if (descr_len > 0) box_length = 9 + no_of_items;
  80.    else box_length = 7 + no_of_items;
  81.    if (box_length > MAX_BOX_LENGTH) 
  82.     box_length = MAX_BOX_LENGTH;
  83.    box_start = SCREEN_H_CENTER - (box_width/2);
  84.    box_line_start = SCREEN_V_CENTER - (box_length/2) 
  85.     - 1;
  86.    return (TRect(box_start,box_line_start,box_start + 
  87.     box_width,box_line_start + box_length));
  88.    }
  89.  
  90. class tcluster_dialog : public TDialog{
  91.    public:
  92.    tcluster_dialog(const char *p_title,
  93.        const char *p_descr,
  94.    void *names_addr, int no_of_items, 
  95.        int item_length);
  96.    TSItem *items[MAX_NO_OF_ITEMS];
  97.    tpstring_array str_array;
  98.    };
  99.  
  100. tcluster_dialog::tcluster_dialog( const char *p_title,
  101.     const char *p_descr, void *names_addr, 
  102.     int no_of_items, int item_length):
  103.     TDialog (the_rect(no_of_items,item_length,
  104.        strlen(p_title),strlen(p_descr)),p_title),
  105.     TWindowInit (&tcluster_dialog::initFrame),
  106.     items ()
  107.    {
  108.    get_tpstring_array (names_addr,no_of_items,
  109.         item_length,str_array);
  110.    //Set up linked list:
  111.    items[no_of_items-1] =
  112.     new TSItem (str_array[no_of_items-1],NULL);
  113.    for (int i = no_of_items - 2; i >=0; --i)
  114.        items[i] = new TSItem (str_array[i],
  115.        items[i+1]);
  116.    TRect r = TRect (2,5+no_of_items,17,7+no_of_items);
  117.    insert (new TButton(r,"O~K~ (Enter)",cmOK,
  118.        bfDefault));
  119.    r = TRect (20,5+no_of_items,35,7+no_of_items);
  120.    insert (new TButton(r,"Cancel (Esc)",cmCancel,
  121.     bfNormal));
  122.    }
  123.  
  124. void radio_dialog (const char *p_title,
  125.          const char *p_descr,void *names, int no_of_items, 
  126.     int item_length, ushort *return_val) {
  127.    ushort radio_dialog_data = *return_val - 1;
  128.    tcluster_dialog *dialog = 
  129.     new tcluster_dialog(p_title,p_descr,names,
  130.     no_of_items,item_length);
  131.    TRect box_r = dialog->getExtent();
  132.    int box_width = box_r.b.x - box_r.a.x;
  133.    TView *b = new TRadioButtons (TRect(2,4,
  134.     box_width - 2,4 + no_of_items),dialog->items[0]);
  135.    dialog->insert(b);
  136.    const label_length = 30;
  137.    char the_label[label_length];
  138.    strcpy(the_label,"~S~elect ");
  139.    strcat(the_label,p_descr);
  140.    strcat(the_label,":");
  141.    dialog->insert(new TLabel(TRect(2,2,box_width - 2,
  142.     3),the_label,b));
  143.    b->select();
  144.    dialog->setData(&radio_dialog_data);
  145.    TApplication *the_app = 
  146.     (TApplication *) dialog->owner;
  147.    the_app->validView (dialog);
  148.    if (dialog != 0) {
  149.       if (gdesk_top->execView(dialog) != cmCancel)
  150.      {
  151.      dialog->getData(&radio_dialog_data);
  152.      *return_val = radio_dialog_data + 1;
  153.      }
  154.       TObject::destroy (dialog);
  155.       }
  156.    }
  157.  
  158. void boolean_dialog (const char *p_title, 
  159.     boolean &answer)  {
  160.    const char yes_no_str[2][6] = {"~Y~es","~N~o"};
  161.    const int two_items = 2;
  162.    const int item_length = 6;
  163.    ushort response;
  164.    if (answer) response = 1;
  165.    else response = 2;
  166.    radio_dialog (p_title,p_title,(void *)yes_no_str,
  167.     two_items,item_length,&response);
  168.    if (response == 1) answer = TRUE;
  169.    else answer = FALSE;
  170.    }
  171.  
  172. // Can also derive a check box dialog from 
  173. //     cluster dialog.
  174.  
  175. class tnum_inputline:public TInputLine {
  176.    public:
  177.    tnum_inputline (const TRect& bounds, int aMaxLen);
  178.    void handleEvent (TEvent& event);
  179.    };
  180.  
  181. tnum_inputline::tnum_inputline(const TRect& bounds, 
  182.     int aMaxLen):TInputLine (bounds,aMaxLen) { }; 
  183.     //Invokes TInputLine (bounds,aMaxlen)
  184.  
  185. void tnum_inputline::handleEvent (TEvent& event) {
  186.    if (event.what == evKeyDown) {
  187.    // Allow only numeric and direction keys
  188.       switch (event.keyDown.charScan.charCode) {
  189.       case '0':   case '1':   case '2':
  190.       case '3':   case '4':   case '5':
  191.       case '6':   case '7':   case '8':
  192.       case '9':   case '.':   case '-':
  193.       case kbEsc: TInputLine::handleEvent (event); 
  194.         return;
  195.       }
  196.       switch (event.keyDown.keyCode) {
  197.       case kbTab:   case kbDel:  case kbEnter:
  198.       case kbHome:  case kbEnd:  case kbRight:
  199.       case kbLeft:  case kbBack:
  200.       case kbEsc: TInputLine::handleEvent (event); 
  201.         return;
  202.       }
  203.       /*  Clear other keyboard events */
  204.       clearEvent(event); return;
  205.       }
  206.    else // Not a keystroke
  207.       TInputLine::handleEvent (event);
  208.       return;
  209.       }
  210.  
  211. void numeric_dialog (const char* p_title,
  212.    int maxlen, int dec_places, boolean check_max_min,
  213.    float min, float max, tdata_type type_of_data,
  214.    void * p_value) {
  215.    const int max_num_length = 10;
  216.    typedef char num_string[max_num_length];
  217.    boolean completed = FALSE;
  218.    do { // until completed
  219.    int line = 5;
  220.    int half_width = maxlen + 8;
  221.    const int MIN_WIDTH = 20;
  222.    if (half_width < MIN_WIDTH) half_width = MIN_WIDTH;
  223.    TRect r (SCREEN_H_CENTER - half_width,
  224.     SCREEN_V_CENTER - line, SCREEN_H_CENTER + 
  225.     half_width, SCREEN_V_CENTER + 1 + line);
  226.    TDialog *dialog = new TDialog (r,p_title);
  227.    half_width = maxlen/2 + 1;
  228.    r = TRect (19 - half_width,4,21 + half_width,
  229.         5);
  230.    tnum_inputline *b = new tnum_inputline (r,
  231.         maxlen + 1);
  232.    dialog -> insert(b);
  233.    r = TRect (2,2,33,3);
  234.    const label_length = 30;
  235.    char the_label[label_length];
  236.    strcpy(the_label,"~E~nter ");
  237.    strcat(the_label,p_title);
  238.    strcat(the_label,":");
  239.    dialog->insert(new TLabel(r,the_label,b));
  240.    line = 6;
  241.    half_width = maxlen + 8;
  242.    if (check_max_min) {
  243.       num_string max_str,min_str;
  244.       sprintf ((char *)&max_str,"%*.*f",maxlen,
  245.         dec_places,max);
  246.       sprintf ((char *)&min_str,"%*.*f",dec_places + 2,
  247.         dec_places,min);
  248.       r = TRect (19 - half_width,line,21 + half_width,
  249.         line + 1);
  250.       strcpy (the_label,"(Min: ");
  251.       strcat (the_label,(char *)&min_str);
  252.       strcat (the_label,", Max: ");
  253.       strcat (the_label,(char *)&max_str);
  254.       strcat (the_label,")");
  255.       dialog->insert(new TStaticText(r,the_label));
  256.       line += 2;
  257.       }
  258.    r = TRect (2,line,17,line + 2);
  259.    dialog -> insert(new TButton(r,"O~K~ (Enter)",cmOK,
  260.     bfDefault));
  261.    r = TRect (20,line,35,line + 2);
  262.    dialog -> insert(new TButton(r,"Cancel (Esc)",
  263.     cmCancel,bfNormal));
  264.    num_string num_data = "";
  265.    switch (type_of_data) {
  266.       case REAL_DATA: {
  267.      sprintf ((char *)&num_data,"%*.*f",maxlen,
  268.         dec_places,*(float *)p_value);
  269.      break;}
  270.       case INT_DATA: {
  271.      sprintf ((char *)&num_data,"%*d",maxlen,
  272.         *(int *)p_value);
  273.      break;}
  274.      }
  275.    dialog -> setData (&num_data);
  276.    b -> select();  //Select input line as focused.
  277.    TApplication *the_app = 
  278.         (TApplication *) dialog->owner;
  279.    the_app->validView (dialog);
  280.    if (dialog != 0) {
  281.       if (gdesk_top->execView(dialog) != cmCancel) {
  282.      dialog -> getData(&num_data);
  283.      char *err_ptr;
  284.      double in_value = strtod (num_data,&err_ptr);
  285.      if (err_ptr != 0) {
  286.         int the_error = 0;
  287.         if (check_max_min)
  288.            if ((in_value < min) || (in_value > max))
  289.           the_error = -1;
  290.         if (the_error == 0) {
  291.            switch (type_of_data) {
  292.          case REAL_DATA: {
  293.             *(float *)p_value = in_value;
  294.             break;}
  295.          case INT_DATA: {
  296.             *(int *)p_value = in_value;
  297.             break;}
  298.          }  //End switch
  299.          completed = TRUE;
  300.          }  //End if (the_error == 0)
  301.          else
  302.         messageBox ("Value out of range.",
  303.             mfError | mfOKButton);
  304.          } // End if (err_ptr != 0)
  305.          else
  306.         messageBox ("Invalid Numeric",
  307.             mfError | mfOKButton);
  308.      }  // End if (... != cmCancel)
  309.      else
  310.         completed = TRUE;  //Cancel command received
  311.      TObject::destroy (dialog);
  312.      } // End if (dialog != 0)
  313.    } while (completed != TRUE);
  314.    } // Function
  315.  
  316. void get_file_name_dlg (const char *pwild_str,
  317.    const char *ptitle_str,char *file_name)
  318.    {
  319.    TFileDialog *dialog =
  320.       new TFileDialog(pwild_str,ptitle_str,"~N~ame",
  321.         fdOpenButton,100);
  322.    TApplication *the_app = 
  323.         (TApplication *) dialog->owner;
  324.    the_app->validView (dialog);
  325.    if (dialog != 0 &&
  326.       gdesk_top->execView(dialog) != cmCancel)
  327.       {
  328.       dialog->getFileName(file_name);
  329.       TObject::destroy (dialog);
  330.       }
  331.    }
  332.  
  333. #endif
  334.